home *** CD-ROM | disk | FTP | other *** search
- /* notes.c
- vi:ts=3 sw=3:
- */
-
- /* $Id: notes.c,v 4.7 1995/02/08 13:14:56 espie Exp $
- * $Log: notes.c,v $
- * Revision 4.7 1995/02/08 13:14:56 espie
- * *** empty log message ***
- *
- * Revision 4.7 1995/02/08 13:14:56 espie
- * *** empty log message ***
- *
- * Revision 4.6 1995/02/01 20:41:45 espie
- * Added color.
- *
- * Revision 4.6 1995/02/01 20:41:45 espie
- * Added color.
- *
- * Revision 4.5 1995/02/01 16:39:04 espie
- * Moved includes to defs.h
- *
- * Revision 4.5 1995/02/01 16:39:04 espie
- * Moved includes to defs.h
- *
- * Revision 4.0 1994/01/11 17:50:04 espie
- * Makes use of autoinit. Uses less memory, starts up faster.
- * auto_init'd create_notes_table(),
- * suppressed note_name static table,
- * use name_of_note() instead (about 120 * 8 bytes gain).
- * Amiga support.
- * Added finetune.
- */
-
- #include "defs.h"
-
- #include <ctype.h>
- #include <assert.h>
- #include <math.h>
-
- #include "song.h"
- #include "channel.h"
- #include "extern.h"
-
- ID("$Id: notes.c,v 4.7 1995/02/08 13:14:56 espie Exp $")
-
-
- /* we can put it autoinit since find_note is ALWAYS called
- * prior to finding note values !
- */
- LOCAL void create_notes_table P((void));
- LOCAL void (*INIT)P((void)) = create_notes_table;
-
-
- /* the musical notes correspond to some specific pitch.
- * It's useful to be able to find them back, at least for
- * arpeggii.
- */
- short pitch_table[NUMBER_NOTES][NUMBER_FINETUNES];
-
- LOCAL char *note_template = "C-C#D-D#E-F-F#G-G#A-A#B-";
-
- /* find_note(pitch): find note corresponding to the stated pitch */
- int find_note(pitch)
- int pitch;
- {
- int a, b, i;
-
- INIT_ONCE;
-
- if (pitch == 0)
- return -1;
- a = 0;
- b = NUMBER_NOTES-1;
- while(b-a > 1)
- {
- i = (a+b)/2;
- if (pitch_table[i][0] == pitch)
- return i;
- if (pitch_table[i][0] > pitch)
- a = i;
- else
- b = i;
- }
- if (pitch_table[a][0] - FUZZ <= pitch)
- return a;
- if (pitch_table[b][0] + FUZZ >= pitch)
- return b;
- return NO_NOTE;
- }
-
- LOCAL void create_notes_table()
- {
- double base, pitch;
- int i, j, k;
-
- for (j = -8; j < 8; j++)
- {
- k = j < 0 ? j + 16 : j;
- base = AMIGA_CLOCKFREQ/440.0/4.0 / pow(2.0, j/96.0);
-
- for (i = 0; i < NUMBER_NOTES; i++)
- {
- pitch = base / pow(2.0, i/12.0);
- pitch_table[i][k] = floor(pitch + 0.5);
- }
- }
- }
-
- char *name_of_note(i)
- int i;
- {
- static char name[4];
-
- if (i == NO_NOTE)
- return " ";
- else
- {
- name[0] = note_template[(i+9)%12 * 2];
- name[1] = note_template[(i+9)%12 * 2 +1];
- name[2] = '0' + (i-3)/12;
- name[3] = 0;
- return name;
- }
- }
-
- int transpose_song(s, transpose)
- struct song *s;
- int transpose;
- {
- int oldt;
- int i, j, n;
-
- if (!s)
- return 0;
- oldt = s->info.transpose;
- for (n = 0; n < s->info.maxpat; n++)
- for (i = 0; i < BLOCK_LENGTH; i++)
- for (j = 0; j < NUMBER_TRACKS; j++)
- if (s->info.pblocks[n].e[j][i].note != NO_NOTE)
- s->info.pblocks[n].e[j][i].note += transpose - oldt;
- s->info.transpose = transpose;
- return oldt;
- }
-